float4x4 World;
float4x4 View;
float4x4 Project;

sampler TextureSampler;

struct VS_INPUT {
    float4 Position : POSITION0;
    float2 Texcoord : TEXCOORD0;
};

VS_INPUT BillboardTransform(VS_INPUT Input) {
    VS_INPUT Output;
    float4x4 vp = mul(View, Project);
    
    float3 cameraY = normalize(vp._m01_m11_m21);   
    float3 cameraZ = -normalize(vp._m02_m12_m22);
    float3 cameraX = normalize(cross(-cameraZ, cameraY));
    
    float3 center = mul(Input.Position, World) - Input.Position; 
    
    float3 position =
		Input.Position.x * cameraX +
		Input.Position.y * cameraY +
		Input.Position.z * cameraZ + center;
    
    Output.Position = mul(float4(position, 1), vp);
    Output.Texcoord = Input.Texcoord;
   
    return Output;
}

float4 Texture(VS_INPUT Input) : COLOR0 {
    return tex2D(TextureSampler, Input.Texcoord);
}

technique Billboard {
    pass P0 {
        VertexShader = compile vs_2_0 BillboardTransform();
        PixelShader  = compile ps_2_0 Texture();
    }
}